package com.shyroke.daydayzhuanweb.controller;

import cn.hutool.core.util.StrUtil;
import com.google.gson.Gson;
import com.shyroke.daydayzhuanapi.constant.SiteDto;
import com.shyroke.daydayzhuanapi.dto.*;
import com.shyroke.daydayzhuanapi.entity.NewsEntity;
import com.shyroke.daydayzhuanapi.entity.RoleEntity;
import com.shyroke.daydayzhuanapi.entity.SpiderInfoEntity;
import com.shyroke.daydayzhuanapi.entity.SpiderProjectEntity;
import com.shyroke.daydayzhuandao.respository.NewsRepository;
import com.shyroke.daydayzhuandao.respository.SpiderInfoRepository;
import com.shyroke.daydayzhuandao.respository.SpiderProjectRepository;
import com.shyroke.daydayzhuandao.respository.UserRepository;
import com.shyroke.daydayzhuansvc.service.ISpiderService;
import com.shyroke.daydayzhuansvc.service.impl.CommitService;
import com.shyroke.daydayzhuansvc.service.impl.ProjectService;
import com.shyroke.daydayzhuansvc.util.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;
import java.net.URL;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * 类名 ：
 * 用法 ：
 * 创建人 ： shyroke
 * 时间：2019/2/21 12:49
 */
@Controller
@RequestMapping(value = "admin/spider")
public class SpiderController {

    @Autowired
    private ISpiderService spiderService;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private CommitService commitService;
    @Autowired
    private NewsRepository newsRepository;
    @Autowired
    private SpiderProjectRepository spiderProjectRepository;
    @Autowired
    private SpiderInfoRepository spiderInfoRepository;
    @Autowired
    private ProjectService projectService;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 跳转爬虫数据列表页面
     * @param model
     * @return
     */
    @RequestMapping(value = "list")
    public ModelAndView list(ModelAndView model,HttpSession session){
        UserMain user = (UserMain)session.getAttribute("user");
        Set<RoleEntity> roleList = userRepository.findByName(user.getName()).getRoleList();
        Boolean isAdmin = UserUtils.isAdmin2(roleList);

        model.addObject("isAdmin",isAdmin);
        model.setViewName("admin/spider/list");

        return model;
    }

    /**
     * 跳转爬虫网站列表页面
     * @param model
     * @return
     */
    @RequestMapping(value = "siteList")
    public ModelAndView siteList(ModelAndView model){

        model.setViewName("admin/spider/siteList");

        return model;
    }

    /**
     * 获取表格的数据
     * @param page
     * @param project
     * @return
     */
    @RequestMapping(value = "getTableData")
    @ResponseBody
    public TabelData<com.shyroke.daydayzhuanapi.dto.SpiderProjectDto> getTableData(Page page, SpiderProjectDto project){
        return spiderService.getTableData(page,project);
    }

    /**
     * 获取爬虫网站表格的数据
     * @param page
     * @param spiderInfo
     * @return
     */
    @RequestMapping(value = "getSiteTableData")
    @ResponseBody
    public TabelData<SpiderInfoDto> getSiteTableData(Page page, SpiderInfoDto spiderInfo){
        return spiderService.getSiteTableData(page,spiderInfo);
    }

    /**
     * 跳转爬虫网站新增页面
     * @param model
     * @return
     */
    @RequestMapping(value = "siteToAdd")
    public ModelAndView siteToAdd(ModelAndView model){

        model.setViewName("admin/spider/siteToAdd");

        return model;
    }


    /**
     * 获取爬虫的目标来源数据
     * @return
     */
    @RequestMapping(value = "getSource")
    @ResponseBody
    public R getSource(){
        List<String> sourceList = spiderService.getSource();

        return R.ok("sourceList",sourceList);
    }

    /**
     *  保存爬虫项目到本站
     * @return
     */
    @RequestMapping(value = "add")
    public ModelAndView add(@RequestParam(value = "id")Integer id,ModelAndView model,HttpSession session,String contentType) throws Exception{

        if( id == null){
            logger.info("保存爬虫项目时，id不能为空！");
            return null;
        }

        SpiderProjectEntity spiderProject = spiderService.getById(id);
        //来源站点名称
        String sourceName = "";
        //来源站点URL
        String sourceURL = "";

        String source = spiderProject.getSource();
        if(!StringUtils.isEmpty(source)){
            String[] sourceArr = source.split(",");
             sourceName = sourceArr[0];
             sourceURL = sourceArr[1];
        }

        ProjectDto project = new ProjectDto();
        //标记该文章为转载
        project.setTitle(spiderProject.getTitle());
        //给文章结尾加上转载链接
//        String sourceDiv = "<br><div>本文转自：<a href = '"+sourceURL+"' target='_black'>"+sourceName+"</a></div>";
        project.setContent(spiderProject.getContent());

        //将相对路径的图片加上域名前缀
        Document document = Jsoup.parse(project.getContent());
        Elements elements = document.select("img");
        Elements Aelements = document.select("a");
        for(Element imgEle:elements){
            //图片放在src/file属性中
            String src = imgEle.attr("src");
            String file = imgEle.attr("file");
            String origin = imgEle.attr("data-original");
            if(!StringUtils.isEmpty(origin)){
                if(!origin.startsWith("http")){
                    origin = sourceURL+origin;
                }
                imgEle.attr("src",origin);
            }else if(!StringUtils.isEmpty(src)){
                if(!src.startsWith("http")){
                    src = sourceURL+src;
                }
                imgEle.attr("src",src);
            }else if (!StringUtils.isEmpty(file)){
                if(!file.startsWith("http")){
                    file = sourceURL+file;
                }
                imgEle.attr("src",file);
            }
            imgEle = imgEle.wrap("<div style='text-align:center'></div>");
        }
        //去除a标签中的域名
        String url = spiderProject.getUrl();
        String host = null;
        if(StrUtil.isNotBlank(url)){
            URL u = new URL(url);
             host = u.getHost();
        }
        for(Element aElement:Aelements){
            aElement.attr("rel","nofollow");
            String href = aElement.attr("href");
            if(!source.contains("yyok")){
                if(href.contains(new URL(sourceURL).getHost())){
                    aElement.removeAttr("href");
                    aElement.tagName("span");
                }
            }
            if(StrUtil.isNotBlank(href) && href.contains("yyok.cc/go")){
                Document descDocument = Jsoup.connect(href).userAgent(SiteDto.CHORME).timeout(50000).get();
                Element urlEle = descDocument.selectFirst("div[class='safety-url']");

                aElement.attr("href", urlEle.text());
            }
        }
        project.setContent(document.html());

        //如果是伪原创则请求5118伪原创
        if(!StringUtils.isEmpty(contentType) && "machine".equals(contentType) && StringUtils.isEmpty(spiderProject.getMachineContent())) {
            String result = commitService.commit5118(project.getContent());
            Gson gson = new Gson();
            MachineRewrite5118Resp resp = gson.fromJson(result, MachineRewrite5118Resp.class);
            if(!resp.getErrcode().equals("0")){
                NewsEntity news = CommonUtil.createNews("5118一键换词失败，失败code="+resp.getErrcode()+",失败原因="+resp.getErrmsg(),1,"5");
                newsRepository.save(news);
            }else{
                String machineContent = resp.getData();
                spiderProject.setMachineContent(machineContent);
                Optional<SpiderProjectEntity> optionalSpiderProjectEntity = spiderProjectRepository.findById(spiderProject.getId());
                if (optionalSpiderProjectEntity.isPresent()) {
                    SpiderProjectEntity spiderProjectEntity = optionalSpiderProjectEntity.get();
                    spiderProjectEntity.setMachineContent(machineContent);
                    spiderProjectRepository.save(spiderProjectEntity);
                }
            }
        }

        UserMain user = (UserMain)session.getAttribute("user");
        Set<RoleEntity> roleList = userRepository.findByName(user.getName()).getRoleList();
        Boolean isAdmin = UserUtils.isAdmin2(roleList);

        model.addObject("isAdmin",isAdmin);
        model.addObject("project",project);
        model.addObject("contentType",contentType);
        model.addObject("machineContent",spiderProject.getMachineContent());
        model.addObject("spiderProjectId",spiderProject.getId());
        model.addObject("topLabels", projectService.getTopLables());
        model.addObject("typeList", projectService.getTypeList(null));
        model.addObject(sourceName);
        model.addObject(sourceURL);

        model.setViewName("admin/spider/add");

        return model;
    }


    /**
     * 重跑爬虫程序
     */
    @RequestMapping(value = "run")
    @ResponseBody
    @PermissionAnnotation(permissionName = "spider:add")
    public R run(){
        //开启多个线程
        return spiderService.spider(null);
    }

    /**
     * 重跑爬虫程序
     */
    @RequestMapping(value = "runSingle")
    @ResponseBody
    @PermissionAnnotation(permissionName = "spider:add")
    public R runSingle(String siteName){
        SpiderInfoEntity spiderInfoEntity = spiderInfoRepository.findBySiteName(siteName);
        return spiderService.spider(spiderInfoEntity);
    }

    /**
     * 保存爬虫网站新增内容
     * @param spiderInfo
     * @return
     */
    @RequestMapping(value = "siteSave")
    @ResponseBody
    public R siteSave(@RequestBody SpiderInfoDto spiderInfo){
        try {
            spiderService.saveSiteInfo(spiderInfo);
            return R.ok("保存成功！");
        }catch (Exception e){
            logger.info("爬虫网站保存异常",e);
            return R.error("保存失败！");
        }
    }

    /**
     * 删除爬虫网站
     * @param siteName
     * @param session
     * @return
     */
    @RequestMapping(value = "siteDelete")
    @ResponseBody
    public R siteDelete(String siteName, HttpSession session){
        try {
            spiderService.deleteBySiteName(siteName);
            return R.ok("删除成功！");
        }catch (Exception e){
            logger.info("删除爬虫网站异常",e);
            return R.error("删除失败！");
        }
    }

    /**
     * 修改爬虫网站信息
     * @param spiderInfo
     * @return
     */
    @RequestMapping(value = "siteUpdate")
    @ResponseBody
    public R siteUpdate(@RequestBody SpiderInfoDto spiderInfo){
        try {
            spiderService.updateSite(spiderInfo);
            return R.ok("保存成功！");
        }catch (Exception e){
            logger.info("保存爬虫网站异常",e);
            return R.error("保存失败！");
        }
    }


    /**
     * 跳转到爬虫网站编辑页面
     * @return
     */
    @RequestMapping(value = "/siteToEdit/{siteName}")
    public ModelAndView siteToEdit(ModelAndView model, @PathVariable("siteName")String siteName){
        model.addObject("info",spiderService.getSiteBySiteName(siteName));
        model.setViewName("admin/spider/siteEdit");
        return model;
    }

    /**
     * 跳转爬虫图片列表页面
     * @param model
     * @return
     */
    @RequestMapping(value = "imgList")
    public ModelAndView imgList(ModelAndView model,HttpSession session){
        model.setViewName("admin/spider/imgList");
        return model;
    }

    /**
     * 爬取图片
     */
    @RequestMapping(value = "imgRun")
    @ResponseBody
    @PermissionAnnotation(permissionName = "spider:add")
    public R imgRun(String type){
        if(StringUtils.isEmpty(type)){
            return R.error("参数不能为空！");
        }
        return spiderService.spiderImg(type);
    }


    /**
     * 删除广告
     * @param id
     * @return
     */
    @RequestMapping(value = "delete")
    @ResponseBody
    public R delete(Integer id){
        if(id == null){
            return R.error("id不能为空！");
        }
        try {
            spiderProjectRepository.deleteById(id);
        }catch (Exception e){
            logger.info("删除失败，原因="+ExceptionUtil.getMessage(e));
            return  R.error("删除失败，原因="+e.getMessage());
        }

        return  R.ok("删除成功！");
    }

}
